﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using PhoenixCrabV6.Engine.IO;

namespace PhoenixCrabV6.Engine.Screens
{
    [DataContract]
    public class ScreenManager
    {
        //Residual of former screen/fadeimage
        //we shouldn't have this
        //public Image Image;
        /// <summary>
        /// Resolution of the current screen
        /// </summary>
        [DataMember] public Vector2 DisplayResolution;
        
        /// <summary>
        /// How long a transition between screens take
        /// </summary>
        [DataMember] public int DefaultTransitionTime;

        [XmlIgnore] public ContentManager Content { private set; get; }
        [XmlIgnore] public GraphicsDevice GraphicsDevice;
        [XmlIgnore] public SpriteBatch SpriteBatch;
        [XmlIgnore] public bool IsTransitioning { get; private set; }

        private IXmlManager<GameScreen> xmlGameScreenManager;
        private GameScreen currentScreen, transitionScreen;
        private int transitionCountdownTimer;

        private static ScreenManager instance;
        public static ScreenManager Instance
        {
            get
            {
                if (instance == null)
                {
                    IXmlManager<ScreenManager> xml = new DataContractManager<ScreenManager>();
                    instance = xml.Load("XML/Screens/ScreenManager.xml");
                }
                return instance;
            }
        }

        public ScreenManager()
        {
            //get the dimensions from the xml file

            DefaultTransitionTime = 3; //3 frames, or 1/20th of a second
            transitionScreen = null;
            transitionCountdownTimer = 0;
           
        }

        /// <summary>
        /// Start changing the screen from current screen to next one
        /// </summary>
        /// <param name="screenName"></param>
        public void ChangeScreens(string screenName)
        {
            ChangeScreens(screenName, DefaultTransitionTime);
        }

        public void ChangeScreens(string screenName, int transitionTime)
        {
            transitionScreen = (GameScreen)Activator.CreateInstance(Type.GetType("PhoenixCrabV6.Engine.Screens." + screenName));
            transitionCountdownTimer = transitionTime;
        }

        public void LoadContent(ContentManager Content)
        {
            currentScreen = new SplashScreen();
            xmlGameScreenManager = new DataContractManager<GameScreen>();
            xmlGameScreenManager.Type = currentScreen.Type;
            currentScreen = xmlGameScreenManager.Load(currentScreen.XmlPath);


            this.Content = new ContentManager(Content.ServiceProvider, "Content");
            
            currentScreen.LoadContent();
        }

        public void UnloadContent()
        {
            currentScreen.UnloadContent();
        }

        public void Update(GameTime gameTime)
        {
            currentScreen.Update(gameTime);
            Transition(gameTime);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            

            //TODO what do do differently if:: if (IsTransitioning)
            if (transitionCountdownTimer > 0 /*&& transitionEffectImage != null*/)
            {
                //if it is transitioning, draw the residual of the former screen
                //Image.Draw(spriteBatch);
                //transitionEffectImage.Image.Draw(spriteBatch);
            }
            else
            {
                currentScreen.Draw(spriteBatch);
            }
                
        }

        /// <summary>
        /// Set preferred resolution as defined by DisplayResolution
        /// </summary>
        /// <param name="graphics"></param>
        public void SetResolution(GraphicsDeviceManager graphics)
        {
            graphics.PreferredBackBufferWidth = (int) ScreenManager.Instance.DisplayResolution.X;
            graphics.PreferredBackBufferHeight = (int) ScreenManager.Instance.DisplayResolution.Y;
            graphics.ApplyChanges();
        }

        private void Transition(GameTime gameTime)
        {
            if (transitionCountdownTimer > 0)
            {
                //is transitioning
                transitionCountdownTimer--;

                if (transitionCountdownTimer <= 0)
                {
                    //just finished transitioning
                    currentScreen.UnloadContent();
                    currentScreen = transitionScreen;
                    //transitionEffectImage = null;
                    transitionCountdownTimer = 0;
                    xmlGameScreenManager.Type = currentScreen.Type;

                    if (File.Exists(currentScreen.XmlPath))
                    {
                        xmlGameScreenManager.Type = currentScreen.Type;
                        currentScreen = xmlGameScreenManager.Load(currentScreen.XmlPath);
                    }
                    currentScreen.LoadContent();
                }
            }
        }

        public void BackDraw()
        {
            currentScreen.BackDraw();
        }
    }
}